package com.bosssoft.trainee.nontax.service.impl;

import com.bosssoft.trainee.nontax.dao.PermissionDao;
import com.bosssoft.trainee.nontax.dao.ResourceDao;
import com.bosssoft.trainee.nontax.dao.RoleDao;
import com.bosssoft.trainee.nontax.dao.RolePermissionDao;
import com.bosssoft.trainee.nontax.entity.dto.TreeNode;
import com.bosssoft.trainee.nontax.entity.po.*;
import com.bosssoft.trainee.nontax.service.AuthorizeService;
import com.bosssoft.trainee.nontax.service.UserRoleService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

@Slf4j
@Service
public class AuthorizeServiceImpl implements AuthorizeService {

    private static final int RESOURCE_ID_OFFSET = 10000;

    @Autowired
    ResourceDao resourceDao;

    @Autowired
    PermissionDao permissionDao;

    @Autowired
    RoleDao roleDao;

    @Autowired
    UserRoleService userRoleService;

    @Autowired
    RolePermissionDao rolePermissionDao;

    /**
     * @Description: 获取所有页面的所有操作
     * @return: java.util.List<com.bosssoft.trainee.nontax.entity.dto.TreeNode>
     * @Author: Luo WenLong
     * @Date: 2022/6/26 13:04
     */
    @Override
    public List<TreeNode> getAllResourceAndAllOptions() {
        ArrayList<TreeNode> treeNodes = new ArrayList<>();
        // 第一层资源页
        List<Resource> resources = resourceDao.queryAll();
        resources.forEach(resource -> treeNodes.add(new TreeNode(
                resource.getResourceId() + RESOURCE_ID_OFFSET,
                resource.getResourceName(),
                null)));

        // 第二层 页操作
        treeNodes.forEach(pageTreeNode -> {
            ArrayList<TreeNode> pageChildrenList = new ArrayList<>();
            List<Permission> permissions = permissionDao.queryAllByResourceId(
                    pageTreeNode.getId() - RESOURCE_ID_OFFSET);
            permissions.forEach(permission -> pageChildrenList.add(new TreeNode(
                    permission.getPermissionId(),
                    permission.getOptionName(),
                    null)));
            pageTreeNode.setChildren(pageChildrenList);
        });

        return treeNodes;
    }

    /**
     * @Description: 获取该角色授权的所有操作
     * @param roleId role id
     * @return: java.util.List<java.lang.Integer>
     * @Author: Luo WenLong
     * @Date: 2022/6/26 13:06
     */
    @Override
    public List<Integer> getRolePermissionIds(Integer roleId) {
        LinkedList<Integer> ids = new LinkedList<>();
        Role role = roleDao.queryById(roleId);
        if (role == null) {
            log.info("fail get permission by role: roleId not in database");
            return ids;
        }
        List<Permission> permissions = permissionDao.queryAllByRoleId(roleId);
        permissions.forEach(permission -> ids.add(permission.getPermissionId()));
        return ids;
    }

    /**
     * @Description: 改变角色于授权用户关系
     * @param roleId role id
     * @param userId user id
     * @param isRoleAuthorizeToUser 是否授权 1授权 -1撤销授权
     * @return: boolean
     * @Author: Luo WenLong
     * @Date: 2022/6/26 13:06
     */
    @Override
    public boolean changeUserRole(Integer roleId, Integer userId, boolean isRoleAuthorizeToUser) {
        int isValid = 1;
        if(isRoleAuthorizeToUser){
            isValid = 0;
        }
        return userRoleService.insertOrUpdate(
                UserRole.builder().roleId(roleId).userId(userId).isValid(isValid).build()) > 0;
    }

    /**
     * @Description: 改变角色授权信息
     * @param roleId role id
     * @param permissionId permission ids 新的授权信息
     * @return: int
     * @Author: Luo WenLong
     * @Date: 2022/6/26 13:07
     */
    @Override
    public int changeRolePermission(Integer roleId, List<Integer> permissionId) {
        List<RolePermission> rolePermissions =
            rolePermissionDao.queryAllByLimit(RolePermission.builder().roleId(roleId).build(), PageRequest.of(0,300));
        AtomicInteger count = new AtomicInteger();
        rolePermissions.forEach(rolePermission -> {
            if(permissionId.contains(rolePermission.getPermissionId())) {
                rolePermission.setIsValid(0);
            }else {
                rolePermission.setIsValid(1);
            }
            count.addAndGet(rolePermissionDao.update(rolePermission));
        });
        return count.get();
    }
}
